import linecache
import os
from typing import Annotated
from fastapi import APIRouter, Depends, Request, Body, Path
from typing import Annotated, Optional

from sanren.utils import get_current_active_user
from application.http import schemas
from application.config import appSettings
from application.http.models import OemModel

router = APIRouter(prefix='/system/extension', tags=['System'])
module_name = '系统模块 - 扩展'

# 日志目录
log_path = os.path.join(appSettings.log_path, 'sanren')

# 生码日志前缀
gen_diy_log_prefix = 'sanren'
gen_abolish_prefix = 'abolish'
gen_log_prefix = 'order.gen.job'
export_log_prefix = 'export.job'
push_log_prefix = 'push.job'


@router.get('/log', response_model=schemas.BaseApiOut)
async def log(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
):
    """
        系统日志列表
    """
    # 主生码日志
    gen_log_files = []
    # 子生码日志
    gen_diy_log_files = []
    # 日志目录
    gen_abolish_files = []
    # 导出日志目录
    export_log_files = []
    # 推送日志目录
    push_log_files = []

    for root, dirs, files in os.walk(log_path):
        for file in files:
            if gen_abolish_prefix in file:
                gen_abolish_files.append({'label': os.path.join(file)})
            elif gen_diy_log_prefix in file:
                gen_diy_log_files.append({'label': os.path.join(file)})
            elif gen_log_prefix in file:
                gen_log_files.append({'label': os.path.join(file)})
            elif export_log_prefix in file:
                export_log_files.append({'label': os.path.join(file)})
            elif push_log_prefix in file:
                push_log_files.append({'label': os.path.join(file)})

    return {
        'data': [
            {
                'label': '自定义日志',
                'children': gen_diy_log_files
            },
            {
                'label': '生码日志',
                'children': gen_log_files
            },
            {
                'label': '导出日志',
                'children': export_log_files
            },
            {
                'label': '作废码日志',
                'children': gen_abolish_files
            },
            {
                'label': '推送日志',
                'children': push_log_files
            },
        ]
    }


@router.get('/log/records', response_model=schemas.BaseApiListOut)
async def log_records(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    page_params: schemas.PageParams = Depends(),
    file: str = None,
):
    """
        系统日志列表
    """

    if file is None or file == '':
        return schemas.base_api_out(code=1, message='非法文件参数')

    # 清空所有缓存
    linecache.clearcache()

    page = page_params.page
    limit = page_params.pageSize
    # 通过 page page_num 计算数量和起始值
    start_num = (page - 1) * limit
    if start_num < 1:
        start_num = 1

    log_file = os.path.join(log_path, file)
    log_datas = [linecache.getline(filename=log_file, lineno=num + start_num) for num in range(limit) if linecache.getline(filename=log_file, lineno=num + start_num)]

    # 格式化数据
    return {
        'data': log_datas,
        'meta': {
            'total': len(log_datas),
        }
    }


@router.get('/log/clear', response_model=schemas.BaseApiListOut)
async def log_clear(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
):
    """
        清空旧日志
    """
    exinclude_files = [
        gen_abolish_prefix + '.log',
        gen_diy_log_prefix + '.log',
        gen_log_prefix + '.log',
        export_log_prefix + '.log',
    ]

    for root, dirs, files in os.walk(log_path):
        for file in files:
            if file not in exinclude_files and (
                gen_abolish_prefix in file or gen_diy_log_prefix in file or gen_log_prefix in file or export_log_prefix in file
            ):
                os.unlink(os.path.join(log_path, file))

    return {'message': '操作成功'}


@router.get('/apps', response_model=schemas.BaseApiListOut)
async def apps(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    page_params: schemas.PageParams = Depends(),
    keyword: Optional[str] = None,
):
    objs = OemModel.ExApp

    if keyword:
        objs = objs.where(
            lambda query: query.where(
                'slug', 'like', f'%{keyword}%'
            ).or_where(
                'name', 'like', f'%{keyword}%'
            ).or_where(
                'version', 'like', f'%{keyword}%'
            ).or_where(
                'remarks', 'like', f'%{keyword}%'
            )
        )

    objs = objs.order_by('id', 'desc').paginate(page_params.pageSize, page_params.page)

    return objs.serialize()


@router.post('/apps', response_model=schemas.BaseApiOut)
async def app_create(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    post: dict = Body(),
):
    if not post['slug'] or not post['name'] or not post['version']:
        return {'status': 1, 'code': 1, 'message': '缺少必要参数(标识|名称|版本)'}

    try:
        insertData = {
            'slug': post['slug'],
            'name': post['name'],
            'version': post['version'],
            'remarks': post['remarks'],
        }
        OemModel.ExApp.create(insertData)

    except Exception as e:
        return {'status': 1, 'code': 1, 'message': f'出错了: {str(e)}'}

    return {'status': 0, 'code': 0, 'message': '创建成功'}


@router.put('/apps/{id}', response_model=schemas.BaseApiOut)
async def app_update(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    post: dict = Body(),
    id: int = Path(...),
):
    print(post['slug'])
    print(post['name'])
    print(post['version'])

    obj = OemModel.ExApp.where('id', id).first()
    if not obj:
        return {'status': 1, 'code': 1, 'message': '找不到此应用信息'}

    if not post['slug'] or not post['name'] or not post['version']:
        return {'status': 1, 'code': 1, 'message': '缺少必要参数(标识|名称|版本)'}

    try:
        obj.slug = post['slug']
        obj.name = post['name']
        obj.version = post['version']
        obj.remarks = post['remarks']
        obj.save()
    except Exception as e:
        return {'status': 1, 'code': 1, 'message': f'出错了: {str(e)}'}

    return {'status': 0, 'code': 0, 'message': '操作成功'}


@router.delete('/apps/{id}', response_model=schemas.BaseApiOut)
async def app_delete(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    id: int = Path(...),
):
    obj = OemModel.ExApp.where('id', id).first()
    if not obj:
        return {'status': 1, 'code': 1, 'message': '找不到此应用信息'}

    if OemModel.ExAppBrand.where('app_slug', obj.slug).first():
        return {'status': 1, 'code': 1, 'message': '此应用已经被使用，不能操作删除'}

    try:
        obj.delete()
    except Exception as e:
        return {'status': 1, 'code': 1, 'message': f'出错了: {str(e)}'}

    return {'status': 0, 'code': 0, 'message': '操作成功'}
